﻿using AntdUI;
using CKS.PLC.Core;
using CKS.PLC.Core.Cache;
using CKS.PLC.Core.Event;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZR.Infrastructure;
using ZR.Model.Models.ProductionControl;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;


namespace CKS.MES.Server
{
    /// <summary>
    /// 主页服务页面
    /// </summary>
    public partial class MainServerForm : AntdUI.Window
    {
        public string _backendUrl = "";

        public MainServerForm()
        {
            InitializeComponent();
            //txtLog.ReadOnly = true;
            this.Text = "MES Server " + PlcCache.CurProductionLine;
            this.FormClosing += MainForm2_FormClosing;
            this.Load += MainForm2_Load;
        }

        private void MainForm2_Load(object sender, EventArgs e) {
            EventBus.AddLogInfoToQueues("MesServer启动成功！");

            var ipAll = ToolsHelper.GetLocalIps();
            foreach (var item in ipAll) {
                EventBus.AddLogInfoToQueues($"本地IP：{item}");
            }

            var app = InternalApp.App;
            var url = app.Urls.First();
            var u = new Uri(url);
            this.Icon = ImageToIcon(pageHeader1.Icon);
            this.StartPosition = FormStartPosition.CenterScreen;
            _backendUrl = $"{u.Scheme}://localhost:{u.Port}/";
            EventBus.AddLogInfoToQueues($"本机服务地址：{_backendUrl}");

            foreach (var localIP in ipAll) {
                EventBus.AddLogInfoToQueues($"局域网服务地址：{u.Scheme}://{localIP}:{u.Port}/");
            }


            EventBus.AddLogInfoToQueues($"当前启动产线：{PlcCache.CurProductionLine ?? "All"}");

            //txtLog.TabStop = false;
            //txtLog.BorderActive = Color.Transparent;
            //txtLog.BorderHover = Color.Transparent;

            this.pageHeader1.Text += $" - {PlcCache.CurProductionLine ?? "All"}";

            _ = IntervalWriteLog();

            Task.Run(UpdatePlcTable);
        }

        private void MainForm2_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dr = AntdUI.Modal.open(new AntdUI.Modal.Config(this, "Message",
                  "Are you sure to exit")
            {
                //禁止使用键盘关闭
                Keyboard = false,
                MaskClosable = false,
                OkText = "Yes",
                CancelText = "No",
            });
            if (dr != DialogResult.OK)
            {
                e.Cancel = true;
            }
        }


        private Icon ImageToIcon(Image image)
        {
            // 创建一个与原始图像大小相同的空白图像
            Bitmap iconBitmap = new Bitmap(64, 64);
            // 使用原始图像绘制空白图像
            using (Graphics graphics = Graphics.FromImage(iconBitmap))
            {
                graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                graphics.DrawImage(image, 0, 0, 64, 64);
            }
            using (Icon icon = Icon.FromHandle(iconBitmap.GetHicon()))
            {
                return Icon.FromHandle(icon.Handle);
            }
        }


        private void btnVisit_Click(object sender, EventArgs e)
        {
            if (!_backendUrl.IsEmpty())
                System.Diagnostics.Process.Start(new ProcessStartInfo(_backendUrl) { UseShellExecute = true });
        }

        /// <summary>
        /// 间隔写入显示日志
        /// </summary>
        /// <returns></returns>
        private Task IntervalWriteLog() {
            var task = Task.Run(async () => {
                try {
                    int maxsize = 99;
                    SafeList<string> logs = new SafeList<string>(maxsize);
                    while (this.IsHandleCreated) {
                        bool AddNew = false;
                        while (EventBus.logQueues.TryDequeue(out string msg)) {
                            logs.Add(msg);
                            AddNew = true;
                        }

                        if (AddNew) {

                            //更新各工位日志
                            foreach (var page in this.tabStationLog.Pages) {

                                if (page.Tag is PlcConfig plcInfo) {
                                    var inputControl = page.Controls.Find($"tabPageInput{plcInfo.WorkstationCode}", true).FirstOrDefault() as AntdUI.Input;
                                    var stationLogs = logs.ToList().Where(l => l.Contains($"{plcInfo.WorkstationCode}") && !l.Contains($"Error") && !l.Contains($"error")).ToList();
                                    if (inputControl != null && stationLogs != null && stationLogs.Count > 0) {

                                        inputControl.Text = string.Join("\r\n", stationLogs);
                                        inputControl.AppendText("\r\n");

                                        inputControl.SelectionStart = inputControl.Text.Length;
                                        inputControl.AutoScroll = true;
                                        inputControl.SelectionLength = 0;
                                        inputControl.ScrollToCaret();
                                    }
                                } else {
                                    var inputControl = page.Controls.Find($"Info", true).FirstOrDefault() as AntdUI.Input;
                                    var stationLogs = logs.ToList().Where(l => !l.Contains($"OP") || l.Contains($"Error") || l.Contains($"error")).Distinct().ToList();
                                    if (inputControl != null && stationLogs != null && stationLogs.Count > 0) {

                                        inputControl.Text = string.Join("\r\n", stationLogs);
                                        inputControl.AppendText("\r\n");

                                        inputControl.SelectionStart = inputControl.Text.Length;
                                        inputControl.AutoScroll = true;
                                        inputControl.SelectionLength = 0;
                                        inputControl.ScrollToCaret();
                                    }
                                }
                            }

                            //txtLog.Text = string.Join("\r\n", logs.ToList().Select(a => $"{a}"));
                            //txtLog.AppendText("\r\n");
                            //txtLog.AutoScroll = true;
                            //if (logs.Count != maxsize)
                            //{
                            //    txtLog.SelectionStart = txtLog.Text.Length; // 将光标移动到文本末尾
                            //    txtLog.SelectionLength = 0; // 确保没有文本被选中
                            //    txtLog.ScrollToCaret(); // 如果需要的话，将滚动条滚动到光标位置
                            //}
                        }
                        await Task.Delay(500);
                    }
                } catch (Exception ex) {
                    EventBus.AddLogErrorToQueues($"日志输出异常，{ex.Message}");
                }
            });
            return task;
        }

        bool isInitTabsPage = false;
        private void UpdatePlcTable() {
            try {

                while (this.IsHandleCreated) {
                    //获取客户端列表，绑定到UI
                    //在线状态，和心跳值。 心跳值是1 绿色，0 是黑色
                    var plcs = PlcCache.PlcClients.ToList().OrderBy(o => o.PlcInfo.SortId).ToList();
                    plcTable.BindPlc(plcs);

                    if (plcs.Count > 0 && !isInitTabsPage) {

                        this.tabStationLog.BeginInvoke(new Action(() => {
                            var tabPage = new AntdUI.TabPage() {
                                Text = "Info",
                            };
                            var input = new AntdUI.Input() {
                                Name = $"Info",
                                ReadOnly = true,
                                Dock = DockStyle.Fill,
                                Multiline = true,
                            };
                            tabPage.Controls.Add(input);
                            this.tabStationLog.Pages.Add(tabPage);
                        }));


                        foreach (var item in plcs.OrderBy(o => o.PlcInfo.SortId).ToList()) {
                            var tabPage = new AntdUI.TabPage() {
                                Text = item.PlcInfo.WorkstationCode,
                                Tag = item.PlcInfo,
                            };
                            var input = new AntdUI.Input() {
                                Name = $"tabPageInput{item.PlcInfo.WorkstationCode}",
                                ReadOnly = true,
                                Dock = DockStyle.Fill,
                                Multiline = true,
                            };
                            tabPage.Controls.Add(input);
                            if (!this.tabStationLog.Pages.Any(a => a.Text == tabPage.Text)) {
                                this.tabStationLog.BeginInvoke(new Action(() => {
                                    this.tabStationLog.Pages.Add(tabPage);
                                }));
                            }
                        }
                        isInitTabsPage = true;
                    }

                    Thread.Sleep(500);
                }
            } catch (Exception ex) {
                MessageBox.Show("获取PLC列表异常：" + ex.Message, caption: "错误消息", buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Error);
            }
        }

    }
}
